Skip to content

Preserve cached retry data when rebuilding Gantt chart#596

Merged
jvanbuel merged 3 commits intomainfrom
claude/fix-gantt-retry-flicker-3euKw
Feb 25, 2026
Merged

Preserve cached retry data when rebuilding Gantt chart#596
jvanbuel merged 3 commits intomainfrom
claude/fix-gantt-retry-flicker-3euKw

Conversation

@jvanbuel
Copy link
Owner

@jvanbuel jvanbuel commented Feb 25, 2026

Summary

This change prevents the Gantt chart from flickering when retry data is being fetched by preserving previously cached try history during chart rebuilds.

Key Changes

  • Modified rebuild_gantt() to preserve cached retry data from the previous Gantt state when fresh data is being loaded
  • Only carries over cached tries if they contain more detailed information than the newly computed data (indicating complete retry history)
  • Made recompute_window() public in GanttData to allow recalculation after updating cached data
  • Refactored rebuild_gantt() to build the new Gantt data separately before applying cache preservation logic

Implementation Details

The rebuild process now:

  1. Creates a fresh GanttData from current task instances
  2. Identifies tasks with retries (try_number > 1)
  3. For each retried task, checks if the old cached data has more tries than the new data
  4. Carries over the cached tries if they're more complete (avoiding data loss during fetch)
  5. Recomputes the window bounds after applying cached data
  6. Replaces the old Gantt data with the updated version

This ensures smooth UX by maintaining detailed retry information while fresh data is being fetched from the server.

https://claude.ai/code/session_01RorM9BtWu7NUZB4yzCPFMQ

Summary by CodeRabbit

  • New Features

    • Gantt view now respects the active DAG run selection, updating displayed data when the DAG run changes.
  • Bug Fixes

    • Task retry history is preserved when Gantt chart data is rebuilt, preventing loss of historical retry information during updates.

When task instances are refreshed, rebuild_gantt() previously replaced
the entire GanttData, wiping out previously fetched retry history. This
caused a visible flicker as retries disappeared momentarily before being
re-fetched from the API. Now, cached retry data is carried over into
the new GanttData when it has more detailed history than the fresh data,
and is only replaced when the new retry fetch completes.

https://claude.ai/code/session_01RorM9BtWu7NUZB4yzCPFMQ
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

Warning

Rate limit exceeded

@jvanbuel has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c0f3fb7 and 90193de.

📒 Files selected for processing (2)
  • src/app/model/taskinstances.rs
  • src/app/state.rs

Walkthrough

Makes GanttData::recompute_window public and updates TaskInstanceModel to track current DAG run, reset cached Gantt data on DAG-run change, and preserve cached retry tries when rebuilding Gantt data; state syncing now sets the DAG run id before loading task instances.

Changes

Cohort / File(s) Summary
Gantt Data Access
src/airflow/model/common/gantt.rs
Changed GanttData::recompute_window visibility from private to pub so external callers can invoke window recomputation.
Task Instance Model
src/app/model/taskinstances.rs
Added current_dag_run_id field and set_dag_run_id(&mut self, &DagRunId); rebuild_gantt now preserves cached retry tries for retried tasks when fresh data has fewer tries, recomputes window, and returns retried task IDs.
State Sync
src/app/state.rs
When dag_id and dag_run_id are present, calls self.task_instances.set_dag_run_id(dag_run_id) before populating task instance table from environment state.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Preserve cached retry data when rebuilding Gantt chart' directly reflects the main objective of the PR—maintaining cached retry information during Gantt chart rebuilds to prevent UI flicker.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-gantt-retry-flicker-3euKw

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/model/taskinstances.rs`:
- Around line 84-92: The cache in gantt_data.task_tries is keyed only by TaskId
and can leak retry history across DAG runs; update the logic to clear or
reinitialize gantt_data (or at least gantt_data.task_tries) when dag_run_id
changes instead of carrying over cached_tries in rebuild_gantt; specifically
detect the dag_run_id switch in sync_panel or in the
WorkerMessage::UpdateTaskInstances handler and reset gantt_data.task_tries (or
the whole gantt_data) before calling rebuild_gantt/merging new_gantt so
cached_tries cannot be applied to a different run.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 282f176 and 2204b65.

📒 Files selected for processing (2)
  • src/airflow/model/common/gantt.rs
  • src/app/model/taskinstances.rs

The gantt_data.task_tries cache is keyed by TaskId, which is reused
across DAG runs of the same DAG. Without tracking which DAG run the
cache belongs to, retry history from a previous run could leak into
a newly selected run via rebuild_gantt()'s carry-over logic.

Add a current_dag_run_id field to TaskInstanceModel and reset
gantt_data when the DAG run changes in sync_panel.

https://claude.ai/code/session_01RorM9BtWu7NUZB4yzCPFMQ
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/app/model/taskinstances.rs`:
- Around line 36-38: Cached gantt_data/task_tries currently only tracks
current_dag_run_id which allows collisions when different DAGs share the same
run id; change the cache key to include both DAG id and run id (e.g., add or
replace current_dag_run_id: Option<DagRunId> with a combined
current_dag_and_run: Option<(DagId, DagRunId)> or add a separate current_dag_id:
Option<DagId>) and update the invalidation logic that checks the run id (the
comparison around task_tries/gantt_data invalidation) to require both dag_id and
dag_run_id match before reusing cached data so caches are not shared across
different DAGs with the same run id.

ℹ️ Review info

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2204b65 and c0f3fb7.

📒 Files selected for processing (2)
  • src/app/model/taskinstances.rs
  • src/app/state.rs

DAG run IDs like "scheduled__2024-01-01T00:00:00" are commonly shared
across different DAGs. The previous cache key (DagRunId only) meant
navigating from DAG A's "run_1" to DAG B's "run_1" would skip the
gantt_data reset since the run ID appeared unchanged.

Replace current_dag_run_id with current_gantt_key: Option<(DagId,
DagRunId)> so the cache is invalidated whenever either the DAG or the
run changes.

https://claude.ai/code/session_01RorM9BtWu7NUZB4yzCPFMQ
@jvanbuel jvanbuel merged commit f143f7e into main Feb 25, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants